// tsconfig.json 的 compilerOptions 中配置了verbatimModuleSyntax 为true，导入类型时必须加type关键字
import axios,{type AxiosInstance,type InternalAxiosRequestConfig,type AxiosResponse,type AxiosError } from 'axios';
import router from "../router";
import {ElMessage, ElMessageBox} from "element-plus";
import {type ApiResponse} from '@/types/base.ts'
import {BusinessCode} from "@/utils/businessCode.ts";
// 创建一个axios实例
const request:AxiosInstance = axios.create({
    baseURL: 'http://localhost:8080', // 你的基础URL
    timeout: 10000, // 请求超时时间
    headers: {
        'Content-Type': 'application/json',
        // 其他默认头信息
    },
    // 其他axios配置...
});
// 添加请求拦截器
request.interceptors.request.use(
    (config: InternalAxiosRequestConfig & { skipBusinessErrorHandle?: boolean }) => {
        // 在发送请求之前做些什么，比如添加token等
        const token = window.localStorage.getItem("token");
        if(token){
            config.headers['token']=token;
        }
        return config;
    },
    (error) => {
        // 对请求错误做些什么
        return Promise.reject(error);
    }
);
// 添加响应拦截器
request.interceptors.response.use(
    (response: AxiosResponse<ApiResponse>) => {
        // 对响应数据做点什么，比如统一处理错误码等
        const config = response.config;
        if ((config as any).skipBusinessErrorHandle) {
            return response;
        }
        //应该处理500 404等错误
        if(response.data.code==BusinessCode.TOKEN_INVALID.code){
            // 使用ElMessageBox.confirm显示一个带有确认按钮的对话框
            ElMessageBox.confirm(
                response.data?.msg || '登录状态已失效或您没有权限操作，请重新登录。',
// 提示消息，优先使用后端返回的，若无则使用默认
                '操作失败', // 标题
                {
                    confirmButtonText: '去登录', // 确认按钮文字
                    cancelButtonText: '取消',
                    type: 'error', // 错误类型图标
                    showClose: false, // 可根据需要决定是否显示关闭按钮
                    closeOnClickModal: false, // 禁止点击遮罩层关闭
                    closeOnPressEscape: false, // 禁止按ESC关闭
                }
            )
                .then(() => {
                    // 用户点击了"去登录"确认按钮
                    // 1. 可选：清除本地无效的token或用户信息
                    localStorage.removeItem('token');
                    // 2. 跳转到登录页面
                    router.replace({
                        path: '/login',
                        query: {
                            from: router.currentRoute.value.fullPath // 传递当前路由路径，以便登录后回跳
                        }
                    });
                })
                .catch((action) => {
                    // 用户点击了"取消"按钮或关闭了对话框 (action === 'cancel' 或 'close')
                    // 可以根据需要决定取消时要执行的操作，例如什么都不做，或者提示用户
                    console.log('用户取消了跳转到登录页');
                });
            return Promise.reject(new Error(response.data.msg || '无权限')
            );
        }
        // 可以根据需要判断其他错误码
        if (response.data.code !== 200 && response.data.code !== 0) {
            ElMessage.error(response.data.msg || '请求失败');
            return Promise.reject(new Error(response.data.msg || 'API error'));
        }
        return response;// 成功情况正常返回
    },
    (error:AxiosError ) => {
        // 对响应错误做些什么
        // 处理 HTTP 网络层错误
        if (error.message.includes('timeout')) {
            ElMessage.error('请求超时，请检查网络');
        } else if (error.message.includes('Network Error')) {
            ElMessage.error('网络连接失败，请检查网络');
        } else if (error.response) {
            const status = error.response.status;
            let msg = '';
            switch (status) {
                case 404:
                    msg = '请求资源不存在';
                    break;
                case 500:
                    msg = '服务器内部错误';
                    break;
                case 502:
                    msg = '网关错误';
                    break;
                case 401:
                    msg='未授权，请重新登录'
                    break
                default:
                    msg = `请求失败，状态码：${status}`;
            }
            ElMessage.error(msg);
        } else {
            ElMessage.error('未知错误');
        }
        return Promise.reject(error); // 向上传递错误
    }
);
// 导出axios实例
export default request;
